package base

import (
	"gitee.com/wm1998/infra"
	"github.com/kataras/iris"
	"github.com/kataras/iris/middleware/logger"
	irisrecover "github.com/kataras/iris/middleware/recover"
	"github.com/sirupsen/logrus"
	"time"
)

// 成员初始化
var irisApplication *iris.Application

// 获取Iris应用实例
func Iris() *iris.Application {
	return irisApplication
}

type IrisServerStarter struct {
	infra.BaseStarter // 包含infra.BaseStarter接口，目的是可以选择性地实现该接口方法
}

// 实现了启动器管理器接口的此方法-1.初始化阶段完成的工作
func (i *IrisServerStarter) Init(ctx infra.StarterContext) {
	// 创建Iris Web框架的应用实例，以供外部调用Iris()时即可获取到Iris实例
	irisApplication = initIris()

	// 日志组件配置和扩展
	logger := irisApplication.Logger()
	// 安装添加一个 golog 处理程序以支持第三方集成
	logger.Install(logrus.StandardLogger())
}

// 实现了启动器管理器接口的此方法-2.启动阶段完成的工作
func (i *IrisServerStarter) Start(ctx infra.StarterContext) {
	routes := Iris().GetRoutes() // 把路由信息打印到控制台
	for _, r := range routes {
		logrus.Info(r.Trace()) // 打印已经注册的路由
	}
	// 从配置中读取配置的端口，如果配置没设置端口，则默认端口为18080
	port := ctx.Props().GetDefault("app.server.port", "18080")
	// 启动Iris Web框架服务
	Iris().Run(iris.Addr(":" + port))
}

// 实现了启动器管理器接口的此方法-3.设置以阻塞方式启动该启动器
func (i *IrisServerStarter) StartBlocking() bool {
	return true
}

// 创建iris的应用实例
func initIris() *iris.Application {
	app := iris.New()
	app.Use(irisrecover.New()) // 自定义recover请求拦截中间件

	cfg := logger.Config{ // 对Iris的日志中间进行设置
		Status: true, // 为true代表要输出到日志文件中
		IP:     true,
		Method: true,
		Path:   true,
		Query:  true,
		// 格式化日志输出，参数分别为：时间戳、请求响应的时间、请求响应的状态、请求的IP、请求方式、请求路径、消息、请求头消息
		LogFunc: func(
			now time.Time, latency time.Duration,
			status, ip, method, path string,
			message interface{},
			headerMessage interface{}) {
			app.Logger().Infof("| %s | %s | %s | %s | %s | %s | %s | %s",
				now.Format("2006-01-02.15:04:05.000000"), latency.String(), status, ip, method, path, headerMessage, message,
			)
		},
	}

	app.Use(logger.New(cfg)) // 设置Iris的日志中间件
	return app
}
